
// 1. 第一步,自己创建一个类继承标准库中的Thread
class Thread1 extends Thread {
    // 2. 第二步,重写run()方法
    public void run() {
        while(true) {
            // run()方法内的就是需要线程执行的逻辑
            System.out.println("hello thread");
            try {
                Thread.sleep(1000); //在每次打印结束后让线程休息1秒
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

class MyRunnable implements Runnable {
    public void run() {
        System.out.println("hello thread2");
    }
}

class TheSumOfTwoNumbers {

}

@FunctionalInterface    // 该注解不是必须的,但是建议加上
interface FunctionalInterfaceDemo1 {
    //抽象方法必须有且只能有一个
    void func1();
    // 其他方法的种类数量则没有要求则不做要求
    default void func2(){};//默认方法
    static void fun3(){};//静态方法
    private void func4(){};//jdk 9+开始也可以有私有方法
}

public class CreateThread {

    // 线程状态
    public static void main(String[] args) throws InterruptedException {
        Thread mainThread=Thread.currentThread();
        Thread t1=new Thread(()-> {
            System.out.println(mainThread.getState());
        });
        t1.start();
        t1.join(5);
    }

    public static void main17 (String[] args) throws InterruptedException {
        Thread mainThread=Thread.currentThread();//获取主线程引用
        Thread t1=new Thread(()-> {
            System.out.println("t1开始等待");
            try {
                mainThread.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("t1等待结束");
        });
        t1.start();
        Thread.sleep(2000);
        System.out.println("main线程结束执行");
    }

    public static void main16(String[] args) throws InterruptedException {
        Thread t1=new Thread(()-> {
           while(true){
               System.out.println("hello t1");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
        });
        System.out.println("主线程开始等待");
        t1.start();
        t1.join(3000);
        System.out.println("主线程等待结束");
    }


    // 线程等待
    public static void main15(String[] args) throws InterruptedException {
        Thread t1=new Thread(()-> {
            for(int i=0;i<3;i++) {
                System.out.println("thread线程开始执行");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("thread线程结束执行");
        });
        t1.start();
        Thread.sleep(4000);
        System.out.println("main线程开始等待");
        t1.join();
        System.out.println("main线程结束等待");
    }


    //使用中断机制进行线程终止
    public static void main14(String[] args) throws InterruptedException {
        Thread t1=new Thread(()-> {
            Thread currentThread=Thread.currentThread();//获取线程引用
            while(!currentThread.isInterrupted()) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                    e.printStackTrace();
                    // 恢复中断状态，让上层代码能检测到
                    Thread.currentThread().interrupt();
                    // 立即返回或结束线程执行
                    return;
                }
            }
        });
        t1.start();
        Thread.sleep(3000);
        t1.interrupt();
    }


    // 自然终止
    public static boolean isQuit=false;
    public static void main13(String[] args) throws InterruptedException {
        Thread t1=new Thread(()-> {
            while(!isQuit) {
                isQuit=true;
                System.out.println("hello thread");
            }
        });
        t1.start();
        Thread.sleep(1000);
    }

    public static void main12(String[] args) throws InterruptedException {
        Thread t1=new Thread(()-> {
            for(int i=0;i<3;i++) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        System.out.println(t1.isAlive());// 在线程启动之前打印
        t1.start();
        t1.start();
        System.out.println(t1.isAlive());//线程启动后打印
        Thread.sleep(3000);
        System.out.println(t1.isAlive());// 主线程休眠3秒后打印
        Thread.sleep(3000);
        System.out.println(t1.isAlive());// 主线程休眠6秒后打印
    }

    //是否是后台线程
    public static void main11(String[] args) {
        Thread t1=new Thread(()-> {
            while(true) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t1.setDaemon(true);//改为后台线程
        System.out.println(t1.isDaemon());
        t1.start();
        System.out.println("hello main");
    }

    public static void main10(String[] args) {
        Thread t1=new Thread(()-> {
            while(true) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t1.start();
        System.out.println(t1.getId());//获取线程ID
        System.out.println(t1.getName());//获取线程名字
        System.out.println(t1.getPriority());//获取线程优先级
    }


    public static void main9(String[] args) {
        Thread t1=new Thread(()-> {
            while(true) {
                System.out.println("hello thread");
            }
        });
        t1.start();
        while(true) {
            System.out.println("hello main");
        }
    }



    public static void main7(String[] args) {
        // 使用匿名内部类来实现
        FunctionalInterfaceDemo1 fl=new FunctionalInterfaceDemo1(){
            public void func1(){
                System.out.println("hello FunctionalInterface");
            }
        };
        //使用Lambda表达式来实现
        FunctionalInterfaceDemo1 fl2=()-> System.out.println("hello FunctionalInterface");

    }

    public static void main6(String[] args) {
        TheSumOfTwoNumbers obj = new TheSumOfTwoNumbers(){
            int sum(int a, int b) {
                return a + b;
            }
        };


    }

    public static void main5(String[] args) {
        Thread t5=new Thread(()-> {
            System.out.println("hello thread5");
        });
        t5.start();
        System.out.println("hello main");
    }

    public static void main8(String[] args) {
        Thread t6=new Thread(()-> System.out.println("hello Runnable"));
        t6.start();
        System.out.println("hello main");
    }

    public static void main4(String[] args) {
        Runnable MyRunnable2=new Runnable() {
            public void run() {
                System.out.println("hello thread4");
            }
        };
        Thread t4=new Thread(MyRunnable2);
        t4.start();
        System.out.println("hello main");
    }

    public static void main3(String[] args) {
        // 通过匿名内部类来创建
        Thread t3=new Thread() {
            public void run() {
                System.out.println("hello thread3");
            }
        };
        t3.start();
        System.out.println("hello main");
    }

    public static void main2(String[] args) {
        MyRunnable myRunnable=new MyRunnable();
        Thread t2=new Thread(myRunnable);
        t2.start();
        System.out.println("hello main");
    }

    public static void main1(String[] args) {
        // 3. 第三步,在main方法中创建类的实例,并调用start()方法.
        Thread1 t1=new Thread1();
        // 调用start()方法,就会创建出一个新线程,这个线程会执行线程中的run()方法
        t1.start();

        while(true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000); //在每次打印结束后让线程休息1秒
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
